package com.xy.smartsms.db.carrierparam;

import android.content.Context;
import android.text.TextUtils;
import com.xy.smartsms.util.Log;
import android.util.LruCache;

import com.xy.smartsms.constant.FacadeConstant;
import com.xy.smartsms.db.carrierparam.entity.WhiteListDb;
import com.xy.smartsms.db.carrierparam.entity.WhiteListItem;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import cn.com.xy.sms.sdk.db.entity.SysParamEntityManager;
import cn.com.xy.sms.sdk.util.StringUtils;

import static com.xy.smartsms.db.carrierparam.entity.WhiteListItem.LEVEL_HIGH;
import static com.xy.smartsms.db.carrierparam.entity.WhiteListItem.LEVEL_NORMAL;

/**
 * Created by admin on 2017/2/24.
 */

public class WhiteListManager {
    public static final String DEFAULT_VERSION = "20170317";
    public static final String LOCAL_WHITELIST_VERSION = "EMBED_WHITELIST_VERSION";

    private LruCache<String, WhiteListItem> mItemCache = new LruCache<String, WhiteListItem>(100);
    private final String TAG = "WhiteListManager";
    private List<WhiteListItem> mSpecialPhoneMap = new ArrayList<WhiteListItem>();
    private Context mContext;

    private WhiteListItem getItem(String phone) {
        WhiteListItem item = mItemCache.get(phone);
        if (item != null && item.getStatus() == WhiteListItem.STATUS_LOAD_SUC_HAS_DATA)
            return item;
        else
            return null;
    }

    public boolean isLoadSuccess(String phone) {
        WhiteListItem item = mItemCache.get(phone);
        if (item != null) {
            return true;
        }
        return false;
    }

    public WhiteListItem preLoadData(final String phone) {
        Log.d(TAG, "preLoadData " + phone);
        WhiteListItem item = mItemCache.get(phone);
        if (item != null && item.getStatus() != WhiteListItem.STATUS_LOAD_DEFULT) {
            return item;
        }
        item = WhiteListDb.getInstance().queryByPhone(phone);
        if (item != null) {
            item.setStatus(WhiteListItem.STATUS_LOAD_SUC_HAS_DATA);
        } else {
            item = isInSectionNos(phone);
            if (item == null) {
                item = new WhiteListItem();
                item.setStatus(WhiteListItem.STATUS_LOAD_SUC_NOT_DATA);
            } else {
                item.setStatus(WhiteListItem.STATUS_LOAD_SUC_HAS_DATA);
            }
        }
        mItemCache.put(phone, item);
        return item;
    }

    private WhiteListItem isInSectionNos(String phone) {
        try {
            String regEx;
            for (WhiteListItem item : mSpecialPhoneMap) {
                regEx = "^(" + item.getNumber() + "){1,1}";
                if (item.getMaxLen() == -1 && item.getMinLen() == -1) {
                    if (item.getLen() == 0) {
                        regEx = regEx + "\\d*$";
                    } else {
                        regEx = regEx + "[0-9]{" + item.getLen() + "," + item.getLen() + "}$";
                    }
                } else if (item.getMaxLen() != -1 || item.getMinLen() != -1) {
                    if (item.getMaxLen() > item.getMinLen()) {
                        regEx = regEx + "[0-9]{" + item.getMinLen() + "," + item.getMaxLen() + "}$";
                    } else {
                        regEx = regEx + "[0-9]{" + item.getMinLen() + "," + "}$";
                    }
                } else
                    return null;
                Pattern pattern = Pattern.compile(regEx);
                Matcher matcher = pattern.matcher(phone);
                if (matcher.matches()) {
                    return item;
                }
            }
        } catch (Throwable e) {
            Log.e(TAG, "isInSectionNos", e);
        }
        return null;
    }

    public boolean checkNormal(String phone) {
        return getItem(phone) != null;
    }

    public boolean checkAdvanced(String phone) {
        WhiteListItem item = getItem(phone);
        if (item == null) {
            return false;
        }
        return item.getLevel() == LEVEL_HIGH;
    }

    public String getAdvancedName(String phone) {
        WhiteListItem item = getItem(phone);
        if (item == null || item.getLevel() == LEVEL_NORMAL) {
            return null;
        }
        return item.getName();
    }

    public void updateOrInsert(WhiteListItem item) {
        WhiteListDb.getInstance().updateOrInsert(item);
        mItemCache.remove(item.getNumber());
    }

    public void delete(WhiteListItem item) {
        WhiteListDb.getInstance().delete(item);
        mItemCache.remove(item.getNumber());
    }

    private WhiteListManager(Context context) {
        mContext = context;
        WhiteListDb.getInstance(mContext);
    }

    private static WhiteListManager sWhiteListManager = null;


    public static WhiteListManager getInstance() {
        return sWhiteListManager;
    }

    public static WhiteListManager getInstance(Context context) {
        synchronized (WhiteListManager.class) {
            if (sWhiteListManager == null) {
                sWhiteListManager = new WhiteListManager(context);
            }
        }
        return sWhiteListManager;
    }

    /**
     * 更新内嵌 号段数据
     */
    public void refreshSectionNo() {
        synchronized (mSpecialPhoneMap) {
            mSpecialPhoneMap = WhiteListDb.getInstance().getAllSpecialPhone();
        }
    }

    private BufferedReader getAssetBufferedReader(String filename) throws Exception {
        InputStream is = mContext.getAssets().open(filename);
        InputStreamReader isr = new InputStreamReader(is, "gbk");
        BufferedReader br = new BufferedReader(isr);
        return br;
    }

    public synchronized void initDataToDb() {
        Log.i(TAG, "initDataToDb: ");
        BufferedReader br = null;
        try {
            br = getAssetBufferedReader(FacadeConstant.WHITE_LIST_VERSION_FILE);
            String whiteVersion = br.readLine();
            if (StringUtils.isNull(whiteVersion)) {
                whiteVersion = DEFAULT_VERSION;
            }

            Log.i(TAG, "file version " + whiteVersion);
            String localVersion = SysParamEntityManager.getStringParam(mContext, LOCAL_WHITELIST_VERSION);
            Log.i(TAG, "current version " + localVersion);
            if (TextUtils.isEmpty(localVersion) || localVersion.compareTo(whiteVersion) < 0) {
                br = getAssetBufferedReader(FacadeConstant.WHITE_LIST_FILE_NAME);
                mSpecialPhoneMap = WhiteListDb.getInstance().initDataToDB(br);
                SysParamEntityManager.setParam(LOCAL_WHITELIST_VERSION, whiteVersion);
            } else {
                mSpecialPhoneMap = WhiteListDb.getInstance().getAllSpecialPhone();
            }
        } catch (Throwable t) {
            Log.i(TAG, "initDataToDb, t =" + t);
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
            } catch (Throwable t) {
                Log.e(TAG, "initDataToDb close", t);
            }
        }
    }

    public void clearCache() {
        if (mItemCache != null)
            mItemCache.evictAll();
        if (mSpecialPhoneMap != null)
            mSpecialPhoneMap.clear();
    }


}
